package com.example.hbase.annotation;

import com.example.hbase.exception.HBaseException;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TypeInfo {

    /** java对象类型 */
    private Class<?> type;
    /** rowKey 列类型 */
    private ColumnInfo rowKey;
    /** java对象处理后的列list */
    private List<ColumnInfo> columnInfos = new ArrayList<>();

    /**
     * 缓存解析结果
     * Qualifier->Family->ColumnInfo.
     * */
    private Map<String, Map<String, ColumnInfo>> columnInfosMap = new HashMap<>();

    /**
     * 从java对象类型解析
     * @param type POJO's type.
     * @return TypeInfo.
     * */
    public static TypeInfo parse(Class<?> type) {
        Assert.notNull(type, "对象类型不能为空");

        TypeInfo typeInfo = new TypeInfo();
        typeInfo.type = type;

        Field[] fields = type.getDeclaredFields();

        for (Field field : fields) {

            field.setAccessible(true);

            ColumnInfo columnInfo = ColumnInfo.parse(type, field);
            if (columnInfo == null) {
                continue;
            }

            //rowKey字段
            if(columnInfo.isRowKey()){
                typeInfo.rowKey = columnInfo;
                continue;
            }
            //其他普通列字段
            typeInfo.columnInfos.add(columnInfo);
        }

        typeInfo.init();

        return typeInfo;
    }

    /**
     * 初始化对象
     * */
    public void init() {
        Assert.notNull(type, "类型不能为空");
        if(CollectionUtils.isEmpty(columnInfos)){
            throw new HBaseException("字段类型集合不能为空");
        }

        int versionFieldCounter = 0;

        for (ColumnInfo columnInfo : columnInfos) {
            if (!columnInfosMap.containsKey(columnInfo.getQualifier())) {
                columnInfosMap.put(columnInfo.getQualifier(), new HashMap<>());
            }
            columnInfosMap.get(columnInfo.getQualifier()).put(columnInfo.getFamily(), columnInfo);
        }

        if (versionFieldCounter > 1) {
            throw new HBaseException("more than one versioned fields.");
        }
    }

    /**
     * 基于列簇+列名找到map中列信息
     * @param family
     * @param qualifier
     * @return
     */
    public ColumnInfo findColumnInfo(String family, String qualifier) {
        Assert.notNull(family, "列簇不能为空");
        Assert.notNull(qualifier, "列名不能为空");
        return columnInfosMap.get(qualifier).get(family);
    }

    private TypeInfo() {
    }

    public Class<?> getType() {
        return type;
    }

    public List<ColumnInfo> getColumnInfos() {
        return columnInfos;
    }

    public ColumnInfo getRowKey() {
        return rowKey;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("-----------------" + getClass()
                + "-----------------------\n");
        sb.append("type=" + type + "\n");
        for (ColumnInfo columnInfo : columnInfos) {
            sb.append(columnInfo + "\n");
        }
        sb.append("-----------------" + getClass()
                + "-----------------------\n");
        return sb.toString();
    }
}
